import * as THREE from '../../build/three.module.js';
import Stats from '../../jsm/libs/stats.module.js';
import { FirstPersonControls } from '../../jsm/controls/FirstPersonControls.js';

const worldWidth = 128;
const worldDepth = 128;

const stats = new Stats();
document.body.appendChild(stats.dom);

const clock = new THREE.Clock();

const scene = new THREE.Scene();
scene.background = new THREE.Color(0xaaccff);
scene.fog = new THREE.FogExp2( 0xaaccff, 0.0007 ); // 迷雾

const k = innerWidth / innerHeight,
      s = 60,
      camera = new THREE.PerspectiveCamera(s, k, 1, 20000);
camera.position.set(0, 200, 0);

const geo = new THREE.PlaneBufferGeometry(20000, 20000, worldWidth - 1, worldDepth - 1);
geo.rotateX(- Math.PI / 2);

const position = geo.attributes.position;
position.usage = THREE.DynamicDrawUsage;

for(let i = 0; i < position.count; i += 1) {
  let y = 35 * Math.sin(i / 2);
  position.setY(i, y);
}

const texture = new THREE.TextureLoader().load('../../textures/water.jpg');
texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
texture.repeat.set(5, 5);

const mtl = new THREE.MeshBasicMaterial({ color: 0x0044ff, map: texture });

const mesh = new THREE.Mesh(geo, mtl);

scene.add(mesh);

const renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio(devicePixelRatio);
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);

const controls = new FirstPersonControls(camera, renderer.domElement);
controls.movementSpeed = 500;
controls.lookSpeed = .1;

const render = () => {
  const delta = clock.getDelta();
  const time = clock.getElapsedTime() * 10;

  const position = geo.attributes.position;

  for(let i = 0; i < position.count; i += 1) {
    let y = 35 * Math.sin(i / 5 + (time + i) / 7);
    position.setY(i, y);
  }

  position.needsUpdate = true;

  controls.update(delta);
  renderer.render(scene, camera);
}

const animation = () => {
  requestAnimationFrame(animation);
  
  render();
  stats.update();
}
animation();

const handleWindowResize = () => {
  camera.aspect = innerWidth / innerHeight;
  camera.updateProjectionMatrix();

  renderer.setSize(innerWidth, innerHeight);

  controls.handleResize();
}

window.addEventListener('resize', handleWindowResize);